Skip to content

S01-02 HTML-HTML5

[TOC]

概述

什么是 HTML5

HTML5是超文本标记语言(HTML)的第五个主要版本,旨在提供更丰富的网页内容和更强大的功能。

特性:

  • 新元素和语义化:HTML5 引入了许多新的元素,以改善文档的结构和语义。常用的新元素包括:

    • <header>:表示文档的头部区域。
    • <footer>:表示文档的底部区域。
    • <article>:表示独立的内容块。
    • <section>:表示文档中的一个区域或章节。
    • <nav>:表示导航链接的部分。
    • <aside>:表示与主内容相关但独立的内容。
  • 多媒体支持:HTML5 提供了对音频和视频的原生支持,使用新的标签:

    • <audio>:用于嵌入音频内容。
    • <video>:用于嵌入视频内容。
  • 表单控件:HTML5 增强了表单的功能,增加了新的输入类型和属性:

    • 新输入类型:如 email、date、number 等,提供更好的用户输入验证。
    • 新属性:如 placeholder、required、autocomplete 等,提高用户体验。
  • Canvas 和 SVG

    • <canvas>:用于绘制图形,支持动态生成和操控图像。
    • SVG:支持可缩放矢量图形,可以创建复杂的图形和动画。
  • 本地存储:HTML5 引入了 Web Storage API,包括:

    • localStorage:用于在浏览器中持久存储数据。
    • sessionStorage:用于在会话期间存储数据。
  • 离线支持

    • Service Workers:通过 Service Workers,HTML5 支持离线 Web 应用,使用户在没有网络连接时仍能访问网站内容。
  • 地理定位:HTML5 允许 Web 应用获取用户的位置数据,使用navigator.geolocation API。

  • API 扩展:HTML5 还引入了多种 API,例如:

    • Web Workers:支持多线程,提升性能。
    • Web Sockets:实现实时双向通信。
    • Drag and Drop:支持拖放操作。
  • 兼容性与渐进增强:HTML5 设计时考虑了向后兼容,老旧浏览器仍然能渲染 HTML5 文档,同时新特性可以渐进式地应用。

优点:

  • 提高可用性和改进用户的友好体验;
  • 有几个新的标签,这将有助于开发人员定义重要的内容;
  • 可以给站点带来更多的多媒体元素(视频和音频);
  • 可以很好的替代 FLASH 和 Silverlight;
  • 当涉及到网站的抓取和索引的时候,对于SEO很友好;
  • 将被大量应用于移动应用程序和游戏;
  • 可移植性好。

缺点: 该标准并未能很好的被 PC 端浏览器所支持。因新标签的引入,各浏览器之间将缺少一种统一的数据描述格式,造成用户体验不佳。

未来趋势:

  • 移动优先
  • 游戏开发者领衔“主演”

HTML发展史

image-20250527154612326

新元素和语义化

新增标签

为了更好地处理今天的互联网应用,HTML5 添加了很多新元素及功能,比如: 图形的绘制,多媒体内容,更好的页面结构,更好的形式 处理,和几个 api 拖放元素,定位,包括网页 应用程序缓存,存储,网络工作者,等。

canvas

标签描述
<canvas>标签定义图形,比如图表和其他图像。该标签基于 JavaScript 的绘图 API

多媒体

标签描述
<audio>定义音频内容
<video>定义视频(video 或者 movie)
<source>定义多媒体资源 <video><audio> 字体
<embed>定义嵌入的内容,比如插件。
<track>为诸如 <video><audio> 元素之类的媒介规定外部文本轨道。

表单

标签描述
<datalist>定义选项列表。请与 input 元素配合使用该元素,来定义 input 可能的值。
<keygen>规定用于表单的密钥对生成器字段。
<output>定义不同类型的输出,比如脚本的输出。

语义和结构:HTML5 提供了新的元素来创建更好的页面结构

标签描述
<article>定义页面的侧边栏内容
<aside>定义页面内容之外的内容。
<footer>定义 section 或 document 的页脚。,可以出现在多个地方
<header>定义了文档的头部区域,,可以出现在多个地方
<nav>定义导航链接。
<progress>定义任何类型的任务的进度。
<section>定义文档中的节(section、区段)。
<time>定义日期或时间。
<mark>定义带有记号的文本。可以用来显示搜索引擎搜索后关键词。
<bdi>允许您设置一段文本,使其脱离其父元素的文本方向设置。
<command>定义命令按钮,比如单选按钮、复选框或按钮
<details>用于描述文档或文档某个部分的细节
<dialog>定义对话框,比如提示框
<summary>标签包含 details 元素的标题
<figure>规定独立的流内容(图像、图表、照片、代码等等)。
<figcaption>定义 <figure> 元素的标题
<meter>定义度量衡。仅用于已知最大和最小值的度量。
<ruby>定义 ruby 注释(中文注音或字符)。
<rt>定义字符(中文注音或字符)的解释或发音。
<rp>在 ruby 注释中使用,定义不支持 ruby 元素的浏览器所显示的内容。
<wbr>规定在文本中的何处适合添加换行符。

移除标签

以下的 HTML 4.01 元素在 HTML5 中已经被删除

  • <acronym> 字体兼容
  • <applet> java 组件
  • <basefont> 字体
  • <big>
  • <center>
  • <dir> 目录
  • <font>
  • <frame>
  • <frameset>
  • <noframes>
  • <strike>

语义标签

语义标签 是 HTML5 中用于增强文档结构和可读性的元素,它们提供了关于内容的含义。

标签描述
<article>定义页面的侧边栏内容
<aside>定义页面内容之外的内容。
<footer>定义 section 或 document 的页脚。可以出现在多个地方
<header>定义了文档的头部区域。可以出现在多个地方
<nav>定义导航链接。
<progress>定义任何类型的任务的进度。
<section>定义文档中的节(section、区段)。

示例:

html
<body>
  <header>定义了文档的头部区域</header>
  <div>
    <article>定义页面的侧边栏内容</article>
    <aside>定义页面内容之外的内容</aside>
  </div>
  <footer>定义 section 或 document 的页脚</footer>
</body>

兼容处理

html5shiv.min.js

思路:

  • 在不支持 HTML5 新标签的浏览器里,会将这些新的标签解析成行内元素(inline)对待,所以我们只需要将其转换成块元素(block)即可使用。

  • 但是在 IE9 版本以下,并不能正常解析这些新标签,但是却可以识别通过document.createElement('tagName')创建的自定义标签。

  • 于是我们的解决方案就是将 HTML5 的新标签全部通过 document.createElement('tagName')来创建一遍,这样 IE 低版本也能正常解析 HTML5 新标签了。

js
//1. 手动创建无法识别的元素
document.createElement('header');
document.createElement('nav');
document.createElement('main');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');

//2. 之后再将所有创建出来的元素转换为块级元素:display: block
header,nav,main,article,aside,footer { display: block; }

处理方式: 在实际开发中我们更多采用的是通过检测 IE 浏览器的版本来加载第三方的一个 JS 库 html5shiv 来解决兼容问题(测试在 IE 下面的兼容性:ieTester 软件的使用)

html
<script src="../js/html5shiv.min.js"></script>

字符集

HTML 与 XHTML 中写法

html
<meta http-equiv="charset" content="utf-8">

HTML5 中写法

html
<meta charset="utf-8">

表单控件

新增表单标签

  • <datalist>:用于为 <input> 元素提供输入建议列表的标签,结合用户输入实现类似“搜索自动补全”的功能。

    • 兼容: FireFox 不支持 value 属性,显示效果不好

    • option 可以是单标签,也可以是双标签

    • 如果 input 的 type 类型是 url 的话,在 datalist 中必须添加http://

    • 允许用户从预定义选项中选择,也支持自由输入。

    • <datalist>id属性和 <input>list 属性关联使用。

    • html
      <input type="text" list="subject" />
      <datalist id="subject">
        <option value="Java" label="使用最广泛"></option>
        <option value="C" label="最基础的语言"></option>
        <option value="PHP" label="我正在学的语言"></option>
      </datalist>

  • <keygen>已废弃,提供一种验证用户数据的可靠方法。在提交表单数据的时候,会生成两个键,一个私钥,一个公钥。私钥存储在本地,公钥发送到服务器。在需要做验证的时候,我们可以从服务器下载一个客户端证书,通过私钥和证书来实现相关的验证操作。(有兼容问题)

  • <progress>:进度条

    • html
      <progress max="100" value="30"></progress>
  • <meter>:度量器,可用于标示级别

    • 属性描述
      highnumber定义度量的值位于哪个点,被界定为高的值。
      lownumber定义度量的值位于哪个点,被界定为低的值。
      maxnumber定义最大值。默认值是 1。
      minnumber定义最小值。默认值是 0。
      optimumnumber定义什么样的度量值是最佳的值。 如果该值高于 "high" 属性,则意味着值越高越好。 如果该值低于 "low" 属性的值,则意味着值越低越好。
      valuenumber定义度量的值。
  • <output>:用于展示内容,只能展示,不能进行编辑(实用性不强)

  • <fieldset>:用于将一组相关的表单元素分组,并提供一个视觉上的框架。通常与 <legend> 标签一起使用,以便为该组元素提供标题。

    html
    <fieldset>
        <legend>个人信息</legend>
        <label for="name">姓名:</label>
        <input type="text" id="name" name="name">
        
        <label for="email">邮箱:</label>
        <input type="email" id="email" name="email">
    </fieldset>

    image-20240919131421028

新增表单属性

  • placeholderstring,占位符。
  • autofocusboolean,是否自动获取焦点。
  • autocompleteon|off,是否自动完成,用于表单元素,也可用于表单自身。
    • 1 必须成功提交过表单。
    • 2 当前添加 autocomplete 的元素必须有 name 属性。
  • multipleboolean,文件上传多选或多个邮箱地址(多个邮箱之间用,号分割)。
  • formstring,指定表单项属于哪个 form,处理复杂表单时会需要。
  • novalidateboolean,关闭验证,可用于<form>标签。
  • requiredboolean,验证条件,必填项。
  • patternRegExp,正则表达式 验证表单。
  • accesskeystring,规定激活(使元素获得焦点)元素的快捷键。采用 Alt + 按键

示例:

html
<form action="" autocomplete="on" id="myForm">
  autofocus定位文本框焦点:<input type="text" autofocus /> <br />
  placeholder设置文本框默认提示:<input type="text" placeholder="请输入***" /><br />
  email邮件类型自带验证和提示:<input type="email" multiple /> <br />
  required属性设置非空特性:<input type="tel" required /><br />
  pattern设置验证规则:<input type="tel" name="tel" required pattern="^(\+86)?1[358]\d{9}$" /><br />
  multiple多文件选择:<input type="file" multiple /><br />
  <input type="submit" value="提交" /><br />
</form>

地址:<input type="text" name="address" form="myForm" />

新增type类型

注意:部分类型是针对移动设备生效的,且具有一定的兼容性,在实际应用当中可选择性的使用。

类型使用示例含义示例
email<input type="email">输入邮箱格式
必须包含@符号
必须包含服务器名称
image-20240919131833469
tel<input type="tel">输入手机号码格式
无验证,移动端打开数字键盘
image-20240919131905603
url<input type="url">输入 url 格式
网址格式验证
必须包含 http://
image-20240919131932980
number<input type="number">输入数字格式
数字格式验证
image-20240919131942954
search<input type="search">搜索框(体现语义化)image-20240919132013474
range<input type="range">自由拖动滑块image-20240919132027079
color<input type="color">拾色器image-20250527160314141
time<input type="time">小时分钟image-20240919132041175
date<input type="date">年月日image-20240919132054633
datetime-local<input type="datetime-local">时间(datetime已废弃)image-20240919132124135
month<input type="month">月年image-20240919132201770
week<input type="week">星期 年image-20240919132219135

新增表单事件

  • oninput输入内容时触发,可用于移动端输入字数统计

  • oninvalid验证不通过时触发

html
<script>
  // oninput:监听用户的每一次输入
  document.getElementById('name').oninput = function () {
    console.log(this.value)
  }

  // onkeyup:监听键盘弹起,每一个键盘弹出触发一次
  document.getElementById('name').onkeyup = function () {
    console.log('---' + this.value)
  }

  // oninvalid:当指定表单元素验证不通过时触发
  document.getElementById('phone').oninvalid = function () {
    console.log('验证不通过')
    this.setCustomValidity('手机号格式不正确!')
  }
</script>

案例

效果图:

代码:

1、样式

html
<style>
  * {
    margin: 0;
    padding: 0;
  }
  body {
    max-width: 600px;
    margin: 0 auto;
  }
  form {
    width: 100%;
  }
  form fieldset {
    padding: 20px 20px 10px;
  }
  form fieldset label {
    font-weight: bold;
    line-height: 20px;
  }
  form input,
  form meter {
    width: 100%;
    margin: 10px 0;
    display: block;
    height: 30px;
    border: 1px solid #ccc;
    padding-left: 5px;
  }
  form meter {
    width: 100%;
    border: none;
    padding-left: 0;
  }
  .btn {
    width: 100%;
    height: 40px;
    margin-top: 20px;
  }
</style>

2、结构

html
<body>
  <form action="">
    <fieldset>
      <legend>学生档案</legend>

      <label for="userName">姓名:</label>
      <input type="text" name="userName" id="userName" placeholder="请输入姓名" required />

      <label for="phone">手机号码:</label>
      <input type="tel" name="phone" id="phone" pattern="^(\+86)?1[358]\d{9}$" />

      <label for="email">邮箱地址:</label>
      <input type="email" name="email" id="email" />

      所属学院:
      <input type="text" list="school" name="college" id="college" placeholder="请选择" />
      <datalist id="school">
        <option>移动与前端开发学院</option>
        <option>IOS</option>
        <option>andriod</option>
        <option>c++</option>
      </datalist>

      <label for="score">入学成绩:</label>
      <input type="number" max="100" min="0" step="1" name="score" id="score" value="0" />

      <label for="level">基础水平</label>
      <!--通过low/high的值来设置meter的颜色-->
      <meter name="level" id="level" value="0" max="100" min="0" low="59" high="90"></meter>

      <label for="inTime">入学日期</label>
      <input type="date" name="inTime" id="inTime" />

      <label for="leaveTime">毕业日期</label>
      <input type="date" name="leaveTime" id="leaveTime" />

      <input type="submit" name="submit" id="submit" class="btn" />
    </fieldset>
  </form>
  <script>
    /*通过score成绩的输入,动态修改meter的颜色*/
    document.getElementById('score').oninput = function () {
      document.getElementById('level').value = this.value
    }
  </script>
</body>

说明:

  • <fieldset>标签将表单内容的一部分打包,生成一组相关表单的字段。当一组表单元素放到<fieldset> 标签内时,浏览器会以特殊方式来显示它们,它们可能有特殊的边界、3D 效果,或者甚至可创建一个子表单来处理这些元素。

  • <legend> 元素为 fieldset 元素定义标题(caption)。

多媒体@

放弃的方式:

  • embed:直接插入视频文件,它的本质是调用本机上已经安装的软件,有兼容性问题。
  • flash 插件:需要安装 flash,需要另外学习 flash,增加了使用成本;苹果设备不支持 flash。

audio

属性:

属性描述
srcurl要播放的音频的 URL。
controlscontrols如果出现该属性,则向用户显示控件,比如播放按钮。
autoplayautoplay如果出现该属性,则音频在就绪后马上播放。
looploop如果出现该属性,则每当音频结束时重新开始播放。
preloadpreload如果出现该属性,则音频在页面加载时进行加载,并预备播放。 如果使用 "autoplay",则忽略该属性。

示例

html
<audio src="../mp3/See.mp3" controls autoplay></audio>

video

属性:

属性说明描述
srcurl要播放的视频的 URL。
controlscontrols如果出现该属性,则向用户显示控件,比如播放按钮。
autoplayautoplay如果出现该属性,则视频在就绪后马上播放。
looploop如果出现该属性,则当媒介文件完成播放后再次开始播放。
preloadpreload如果出现该属性,则视频在页面加载时进行加载,并预备播放。 如果使用 "autoplay",则忽略该属性。
widthpixels设置视频播放器的宽度。
heightpixels设置视频播放器的高度。(宽、高只设置一个,另一个自动调节
posterurl视频封面,当视频还没有完全下载,或用户还没有点击播放前的默认显示画面,默认显示当前视频文件的第一帧

示例:

html
<video src="../mp4/561902ae6ac6e6649.mp4" controls></video>

source

<source> 标签用于在 HTML5 中为 <audio><video> 标签提供多个媒体资源。它允许浏览器选择最合适的格式播放。每个 <source> 标签可以指定不同的文件和类型。

示例

html
<!-- 考虑到不同浏览器支持的视频格式不同 -->
<video controls>
  <source src="../mp4/561902ae6ac6e6649.mp4" type="video/mp4" />
  <source src="../mp4/561902ae6ac6e6649.ogg" type="video/ogg" />
  您的浏览器不支持当前的视频格式
</video>

说明: 由于版权等原因,不同的浏览器可支持播放的格式是不一样的

image-20250525153116991

embed(废弃)

embed:可以用来插入各种多媒体,格式可以是 Midi、Wav、AIFF、AU、MP3 等等。src 为音频或视频文件及其路径,可以是相对路径或绝对路径。

注意: 大多数现代浏览器已经弃用并取消了对浏览器插件的支持,所以如果你希望你的网站可以在普通用户的浏览器上运行,那么依靠 <embed> 通常是不明智的

因为兼容性问题,我们这里只讲解 插入网络视频, 后面 H5 会讲解 audio 和 video 视频多媒体。

示例

html
<embed src="http://player.youku.com/player.php/sid/XMTI4MzM2MDIwOA==/v.swf"
       allowFullScreen="true"
       quality="high"
       width="480"
       height="400"
       align="middle"
       allowScriptAccess="always"
       type="application/x-shockwave-flash">
</embed>

HTMLMediaElement

HTMLMediaElement 是一个用于处理媒体(音频和视频)元素的接口,它是 HTML5 的一部分,提供了一系列操作和控制媒体播放的功能。这个接口是 HTMLAudioElementHTMLVideoElement 的父类

  • 常用属性:
  • srcstring,获取或设置媒体的 URL。
  • currentTimedouble单位:秒获取设置当前播放时间。
  • durationdouble单位:秒,返回媒体的总时长。
  • pausedboolean,返回一个布尔值,指示媒体是否处于暂停状态。
  • endedboolean,返回一个布尔值,指示媒体是否已播放完毕。
  • volumedouble,获取或设置音量(范围从 0.0 到 1.0)。
  • mutedboolean,获取或设置媒体是否被静音。
  • playbackRatedouble,获取或设置播放速度(默认为 1.0)。
  • readyStatenumber,返回媒体的准备状态(0-4),表示加载的进度。
  • 常用方法:
  • play()(),开始播放媒体。
  • pause()(),暂停媒体播放。
  • load()(),重新加载媒体。
  • canPlayType()(type),检查浏览器是否支持特定类型的媒体格式。
  • 常用事件:
  • play:``,媒体开始播放。
  • canplay:``,用户可以开始播放视频或音频时触发。
  • pause:``,媒体暂停。
  • ended:``,媒体播放结束。
  • timeupdate:``,当前播放位置发生变化。
  • volumechange:``,音量或静音状态发生变化。
  • error:``,播放过程中发生错误。

案例:自定义播放器

1、页面结构

html
<h3 class="playerTitle">视频播放器</h3>
<div class="player">
  <video src="../mp3/test.mp4"></video>
    
  <!-- 播放控制条 -->
  <div class="controls">
    <a href="javascript:;" class="switch fa fa-pause"></a>
    <a href="javascript:;" class="expand fa fa-expand"></a>
    <div class="progress">
      <div class="bar"></div>
      <div class="loaded"></div>
      <div class="elapse"></div>
    </div>
    <div class="time">
      <span class="currentTime">00:00:00</span>
      \
      <span class="totalTime">00:00:00</span>
    </div>
  </div>
</div>

2、JS代码

  • 暂停、播放切换

  • 全屏

  • canplay中格式化显示视频总时长、显示视频标签

  • timeupdate中格式化显示当前播放时间、当前播放进度条

  • click中点击进度条跳转到指定播放进度

    image-20240924164808021

  • ended中播放完毕后,重置播放状态

    image-20240924164749372

html
<script src="../js/jquery.min.js"></script>
<script>
  /* 获取到播放器 */
  var video = $('video')[0]
  
  /* 暂停-播放切换 */
  $('.switch').click(function () {
    //1.切换样式,从暂停切换到播放,或者从播放切换到暂停
    $(this).toggleClass('fa-pause fa-play')
    //2.修改播放器的状态
    if (video.paused) {
      video.play()
    } else {
      video.pause()
    }
  })

  /* 全屏 */
  $('.expand').click(function () {
    video.webkitRequestFullScreen()
  })

  /* 当可以进行播放的时候触发oncanplay */
  video.oncanplay = function () {
    setTimeout(function () {
      video.style.display = 'block'
      //1.获取视频的总时长,结果以秒作为单位
      var duration = video.duration
      /*console.log(duration);*/ //256.278
      //2.计算 时  分  秒
      var hour = Math.floor(duration / 3600)
      var menite = Math.floor((duration % 3600) / 60)
      var second = Math.floor(duration % 60)
      //3.将时分秒信息填充到总时长span中
      //3.1 设置时分秒的格式
      hour = hour < 10 ? '0' + hour : hour
      menite = menite < 10 ? '0' + menite : menite
      second = second < 10 ? '0' + second : second
      //3.2填充
      $('.totalTime').html(hour + ':' + menite + ':' + second)
    }, 2000)
  }
    
  /* 当视频在播放的时候,会触发下下面的方法ontimeupdate */
  video.ontimeupdate = function () {
    //1.获取当前已经播放过了时间
    var elapseTime = video.currentTime
    //2.获取已过时间的时分秒
    var hour = Math.floor(elapseTime / 3600)
    var menite = Math.floor((elapseTime % 3600) / 60)
    var second = Math.floor(elapseTime % 60)
    //3.将时分秒信息填充到当前时长span中
    //3.1 设置时分秒的格式
    hour = hour < 10 ? '0' + hour : hour
    menite = menite < 10 ? '0' + menite : menite
    second = second < 10 ? '0' + second : second
    //3.2填充
    $('.currentTime').html(hour + ':' + menite + ':' + second)
    //4.设置当前<div class="elapse"></div>的宽度
    var valuePercent = 0
    if (elapseTime > 0) {
      valuePercent = (elapseTime / video.duration) * 100
      $('.elapse').css('width', valuePercent + '%')
    }
  }
</script>

3、效果

image-20240924153633827

DOM 扩展@

获取DOM元素

  • document.getElementsByClassName() / el.getElementsByClassName()(classNames),返回匹配给定类名的元素列表。

  • document.querySelector() / el.querySelector()(selectors),返回文档中与指定的选择器匹配的第一个元素节点

    js
    const element = document.querySelector('selector');
  • document.querySelectorAll() / el.querySelectorAll()(selectors),返回包含文档中与指定的选择器匹配的所有元素节点的列表。

    js
    const elements = document.querySelectorAll('selector');

    注意: NodeList 不是一个真正的数组,但可以像数组一样使用索引访问元素后使用forEach()遍历。可以使用 Array.from() 或扩展运算符将其转换为数组,以便使用数组方法。

    js
    // 1. 使用forEach遍历NodeList
    elements.forEach((element) => {
        console.log(element);
    });
    
    // 2. 使用Array.from()转换为数组
    const elementArray = Array.from(elements);

类名操作

注意: 以下方法一次都只能操作一个样式。

image-20240923214746886

自定义属性data-*

自定义属性:在 HTML5 中我们可以通过data-xxx=""自定义属性。例如:data-info="我是自定义属性"

获取自定义属性值:通过Node.dataset['xxx']我们便可以获取到自定义的属性值。

注意: 当我们如下格式设置时,则需要以驼峰格式才能正确获取:data-my-name="itcast",获取Node.dataset['myName']


相关属性

el.datasetDOMStringMap,用于访问和操作 HTML 元素的自定义数据属性(data-* 的属性。

案例: tab标签页

1、练习重点:

  • 获取元素的方式
  • 自定义属性的使用
  • 类名操作:如添加类样式,移除类样式

2、效果图

3、结构

html
<div class="tabs">
  <div>
    <a href="javascript:;" data-target="local">国内新闻</a>
    <a href="javascript:;" data-target="global">国际新闻</a>
    <a href="javascript:;" data-target="sports">体育新闻</a>
    <a href="javascript:;" data-target="funny">娱乐新闻</a>
  </div>
</div>
html
<div>
  <section class="cont active" id="local">
    <ol>
      <li>习近p向2名晋升为上将军官颁发命令状</li>
      <li>郭声琨了解指导公安消防部队抗洪工作</li>
      <li>媒体:曾任职中办的这位官员仕途有变</li>
      <li>广西警方端掉地下兵工厂缴获大批炮弹</li>
      <li>她完美诠释奇葩考题夺金牌</li>
      <li>中国奥运选手在里约多次遭抢劫</li>
    </ol>
  </section>
  <section class="cont active" id="global">
    <ol>
      <li>河南再次发生矿难,死伤人数超过100</li>
      <li>禽流感次发生蔓延,温家宝指示</li>
      <li>南方大旱,农作物减产绝收面积上亩</li>
      <li>猪流感在广减产绝收发</li>
      <li>禽流感在全国多作物减产绝收面积上亩</li>
      <li>猪流感在广东群体性暴发</li>
    </ol>
  </section>
  <section class="cont" id="sports">
    <ol>
      <li>河南再次发生矿难,死伤人数超过10</li>
      <li>禽流感在全国多处农作物农延,温家宝指示</li>
      <li>南方大旱,农作物减产绝收面积上亩</li>
      <li>猪流感在广东群体性暴发</li>
      <li>禽流感在全农作物继续蔓延,温家宝指示</li>
      <li>南方大农作物减产绝收面积上亩</li>
      <li>猪流感在广东群体性暴发</li>
    </ol>
  </section>
  <section class="cont" id="funny">
    <ol>
      <li>福建发生血腥命案:两女遭割喉 1男孩被砍数刀</li>
      <li>四川原副省长李成云被查 5年前曾违纪又复出</li>
      <li>胡歌反对粉丝探班:以前请吃饭现在会黑脸</li>
      <li>曝郑爽爸爸歌厅撩妹 与女子勾肩搭背显亲密</li>
      <li>宜宾公安副局长无证驾驶出车祸 弃车离开现场</li>
      <li>国子监大街门匾现错字 已悬挂近10年(图)</li>
      <li>猪流感在广东群体性暴发</li>
    </ol>
  </section>
</div>

4、JS 代码

js
;(function (key) {
  //1.获取所有a标签
  var allA = document.querySelectorAll('.tabs > div > a')
  //初始化操作
  for (var i = 0; i < allA.length; i++) {
    if (i == key) {
      allA[i].classList.add('active')
      var active = allA[i].dataset['target']
      document.querySelector('#' + active).style.display = 'block'
    }
    //2.循环遍历所有的a标签,为其添加点击事件
    allA[i].onclick = function () {
      //3.判断当前是否是当前已激活的页,如果是,则不进行处理
      if (this.classList.contains('active')) {
        return
      }
      //4.否则,则需要找到当前a标签对应的data-target属性,利用这个属性找到对应id的section进行样式的设置,让其显示
      //4.1先移除之前a标签的active类样式
      var aActive = document.querySelector('.active')
      aActive.classList.remove('active')
      //4.2让之前显示的section隐藏
      var currentTarget = aActive.dataset['target']
      document.querySelector('#' + currentTarget).style.display = 'none'
      //4.3为其添加active样式
      this.classList.add('active')
      //4.4获取当前被点击的a标签的data-target属性
      var value = this.dataset['target']
      //4.5让对应id的section显示--添加active类样式即可
      document.querySelector('#' + value).style.display = 'block'
    }
  }
})(0)

网络状态@

我们可以通过 window.online 来检测,用户当前的网络状况,事件参数可以返回一个布尔值。

  • window.online:用户网络连接时被调用。

  • window.offline:用户网络断开时被调用。

示例:

js
/*网络连接时调用*/
window.addEventListener('online', function (e) {
  console.log('ok')
  console.log(e.type) // online
})

/*网络断开时调用*/
window.addEventListener('offline', function (e) {
  console.log('no')
  console.log(e.type) // offline
})

全屏@

注意:以下方法和属性有兼容问题。

方法和属性

  • el.requestFullScreen()(options?)不兼容,用于将指定元素切换至全屏模式的方法,通过用户交互触发(如点击事件)。
  • document.exitFullScreen()()不兼容,用于退出全屏模式的方法。允许开发者通过代码控制退出全屏状态,而不是依赖用户手动操作(如按 ESC 键)。
  • document.fullScreenElementElement不兼容只读,用于获取当前处于全屏模式的 DOM 元素,直接通过 document 对象访问。

示例

js
// 处理兼容问题
btn.onclick = function () {
  /* 能力测试:使requestFullScreen()兼容所有浏览器 */
  if (docuEle.requestFullScreen) {
    document.getElementById('img').requestFullScreen()
  } else if (docuEle.webkitRequestFullScreen) {
    document.getElementById('img').webkitRequestFullScreen()
  } else if (docuEle.mozRequestFullScreen) {
    document.getElementById('img').mozRequestFullScreen()
  } else if (docuEle.msRequestFullScreen) {
    document.getElementById('img').msRequestFullScreen()
  } else if (docuEle.oRequestFullScreen) {
    document.getElementById('img').oRequestFullScreen()
  }

  // 判断是否全屏
  if (
    document.fullscreenElement ||
    document.webkitFullscreenElement ||
    document.mozFullScreenElement ||
    document.msFullscreenElement ||
    document.oFullscreenElement
  ) {
    alert('全屏')
  } else {
    alert('不是全屏')
  }
}

FileReader@

FileReader:是一个 Web API,允许网页应用异步读取用户的文件。它主要用于处理用户通过 <input type="file"> 上传的文件。

注意:通过实例方法读取到的结果可以在load事件函数中通过reader.result 或者e.target.result获取到。

实例属性

  • reader.resultstring|ArrayBuffer|null只读,访问读取结果
  • reader.errorDOMException|null,用于获取文件读取过程中发生的错误信息
  • reader.readyState0|1|2只读,获取当前读取状态

实例方法

  • new FileReader()()构造函数,创建一个新的 FileReader 实例。
  • reader.readAsText()(file,encoding?),以文本形式异步读取文件内容。
  • reader.readAsDataURL()(file),将文件内容转换为 Base64 编码的 Data URL,可直接用于嵌入网页(如图片预览)。
  • reader.readAsArrayBuffer()(file),将文件内容读取为 ArrayBuffer 对象(二进制数据的底层容器),用于直接操作二进制数据。
  • reader.abort()(),立即中止正在进行的文件读取操作。

事件

  • loadevent,读取成功完成时触发。

  • errorevent,当读取由于错误而失败时触发。

  • abortevent,当读取被中止时触发,例如因为程序调用了 FileReader.abort() 方法。

  • progressevent,读取数据时持续触发。

  • loadendevent,读取完成时触发,无论成功与否。

  • loadstartevent,读取开始时触发。

拖拽@

拖拽(Drag and Drop)功能允许用户通过鼠标操作在网页上移动元素。这一特性增强了用户交互体验,可以用于文件上传列表排序等场景。

API

1、设置可拖拽元素:在待拖拽元素上添加 draggable 属性,设为 true。链接和图片默认是可拖动的,不需要 draggable 属性

2、监听事件

  • 被拖拽元素上触发的事件:
  • dragstart(e) => void,用户开始拖动元素时触发。
  • dragend(e) => void,用户完成元素拖动后触发。
  • drag(e) => void元素正在拖动时触发(持续触发)。每隔 350 毫秒触发一次。
  • dragleave(e) => void,当鼠标离开拖拽元素时调用。
  • 目标元素上触发的事件:
  • dragenter(e) => void,当被鼠标拖动的对象进入其容器范围内时触发此事件。
  • dragleave(e) => void,当被鼠标拖动的对象离开其容器范围内时触发此事件。
  • dragover(e) => void,当某被拖动的对象在另一对象容器范围内拖动时触发此事件(持续触发)。
  • drop(e) => void,在一个拖动过程中,释放鼠标键时触发此事件。
    • 注意:浏览器默认会阻止drop事件触发,必须在dragover中阻止浏览器的默认行为。

3、事件对象 e:

扩展: 区分-currentTarget、target

  • eDragEvent ,继承 MouseEventEvent,用于处理拖拽操作的事件对象,包含了与拖拽相关的信息和属性。

    • currentTargetElement,表示当前正在处理事件的元素,即绑定事件处理函数的元素

    • targetElement,表示触发事件的元素,即用户实际操作的元素。

    • dataTransferDataTransfer,用于存储和管理拖拽过程中传输的数据。可以设置或获取要传输的数据

      • setData()(format, value),设置要传输的数据。
        • formattext/plain | text/uri-list,拖动数据的类型。
        • valuestring,要添加的数据。
      • getData()(format),获取要传输的数据。只能在drop事件中取值
        • formattext/plain | text/uri-list,拖动数据的类型。
      • effectAllowedcopy | move | link,表示当前拖动操作允许的效果。通过设置此属性,可以控制用户在拖拽时的行为。
      • dropEffectnone | copy | move | link,表示放置操作的效果。这个属性可以在拖拽结束时被设置,以指示放置的实际效果。
    • html
      <div id="draggable" draggable="true">拖动我</div>
      <div id="dropzone">放到这里</div>
      
      <script>
          const draggable = document.getElementById('draggable');
          const dropzone = document.getElementById('dropzone');
      
          draggable.addEventListener('dragstart', (event) => {
              event.dataTransfer.setData('text/plain', '拖动的数据');
              event.dataTransfer.effectAllowed = 'move'; // 设置允许的效果
          });
      
          dropzone.addEventListener('dragover', (event) => {
              event.preventDefault(); // 允许放置
              event.dataTransfer.dropEffect = 'copy'; // 设置放置效果
          });
      
          dropzone.addEventListener('drop', (event) => {
              event.preventDefault();
              const data = event.dataTransfer.getData('text/plain');
              dropzone.textContent = `放置的内容: ${data}`;
          });
      </script>

基本实现

html
    <div class="container">
      <div class="div1">
        <p class="p1" draggable="true">拖拽我</p>
      </div>
      <div class="div2"></div>
    </div>

    <script>
      // 实现元素拖拽
      window.onload = function () {
        let p1 = document.querySelector('.p1')
        let div1 = document.querySelector('.div1')
        let div2 = document.querySelector('.div2')

        // 被拖拽元素
        p1.addEventListener('dragstart', function (e) {
          console.log('dragstart')
        })
        p1.addEventListener('drag', function (e) {
          // console.log('drag...')
        })
        p1.addEventListener('dragend', function (e) {
          console.log('dragend')
        })
        p1.addEventListener('dragleave', function (e) {
          console.log('被拖拽元素:dragleave')
        })

        // 目标元素
        div2.addEventListener('dragenter', function (e) {
          console.log('dragenter')
        })
        div2.addEventListener('dragover', function (e) {
          // 阻止默认行为
          e.preventDefault()
          // console.log('dragover...')
        })
        div2.addEventListener('dragleave', function (e) {
          console.log('目标元素:dragleave')
        })
        div2.addEventListener('drop', function (e) {
          // 阻止默认行为
          e.preventDefault()
          console.log('drop')
          // 添加p1到div2中
          div2.appendChild(p1)
        })
      }
    </script>

通用-多元素拖拽

思路:

  • 使用document代替了p1、div1、div2,这里利用了事件的捕获特性。
  • 通过e.target获取当前事件发生的元素对象。
  • 通过e.dataTransfer.setData()e.dataTransfer.getData()方法实现不同拖拽事件之间的数据传递。
html
  <div class="container">
      <div class="div1">
        <p class="item p1" draggable="true">拖拽我</p>
        <p class="item p2" draggable="true">拖拽我2</p>
      </div>
      <div class="div2"></div>
      <div class="div3"></div>
    </div>

    <script>
      // 实现元素拖拽
      window.onload = function () {
        let div1 = document.querySelector('.div1')
        let div2 = document.querySelector('.div2')

        // 被拖拽元素
        document.addEventListener('dragstart', function (e) {
          console.log('dragstart')
          e.dataTransfer.setData('text/plain', e.target.classList[1]) // p1
        })
        document.addEventListener('drag', function (e) {
          // console.log('drag...')
        })
        document.addEventListener('dragend', function (e) {
          console.log('dragend')
        })
        document.addEventListener('dragleave', function (e) {
          console.log('被拖拽元素:dragleave')
        })

        // 目标元素
        document.addEventListener('dragenter', function (e) {
          console.log('dragenter')
        })
        document.addEventListener('dragover', function (e) {
          // 阻止默认行为
          e.preventDefault()
          // console.log('dragover...')
        })
        document.addEventListener('dragleave', function (e) {
          console.log('目标元素:dragleave')
        })
        document.addEventListener('drop', function (e) {
          console.log('drop')
          // 添加被拖拽元素到目标元素中
          let pClass = e.dataTransfer.getData('text/plain')
          e.target.appendChild(document.querySelector('.' + pClass))
        })
      }
    </script>

地理定位@

地理定位 API(Geolocation API):是一个用于获取用户地理位置信息的浏览器接口。它允许网页应用访问设备的位置信息,适用于需要定位服务的应用场景,例如地图服务、位置共享和基于位置的推荐等。

获取地理信息方式:

浏览器会自动以最优方式去获取用户地理信息。

image-20240924125511473

安全性:

HTML5 Geolocation(地理位置定位) 规范提供了一套保护用户隐私的机制。必须先得到用户明确许可,才能获取用户的位置信息。

注意:在国内即使允许了获取用户位置信息,也是无法获取到定位信息的(GFW),只有在手机上可以获取到定位信息。

API

百度地图

百度地图坐标拾取器

百度地图文档

本地存储

需求

随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,传统方式我们以 document.cookie 来进行存储的,但是由于其存储大小只有 4k 左右,并且解析也相当的复杂,给开发带来诸多不便,HTML5 规范则提出解决方案

HTML5 提供的解决方案

  • window.sessionStorage
  • window.localStorage

特点

  • 设置、读取方便
  • 容量较大,大约 5M
  • 只能存储字符串,可以将对象 JSON.stringify() 编码后存储

sessionStorage

示例

html
<script>
  var userData = document.getElementById('userName')
  //存储数据
  document.getElementById('setData').onclick = function () {
    window.sessionStorage.setItem('userName', userData.value)
  }

  //获取数据
  document.getElementById('getData').onclick = function () {
    var value = window.sessionStorage.getItem('userName')
    alert(value)
  }
</script>

localStorage

特点

  • 永久生效,除非手动删除:存储在硬盘上
  • 可以多窗口共享。但是不能跨浏览器

示例

html
<script>
  var userData = document.getElementById('userName')
  //存储数据
  document.getElementById('setData').onclick = function () {
    window.localStorage.setItem('userName', userData.value)
  }

  //获取数据
  document.getElementById('getData').onclick = function () {
    var value = window.localStorage.getItem('userName')
    alert(value)
  }

  //删除数据
  document.getElementById('removeData').onclick = function () {
    window.localStorage.removeItem('userName')
  }
</script>

应用缓存(弃用)

概述

应用缓存(Application Cache):是 HTML5 提供的一种机制,允许 web 应用程序在离线时仍然可用

替代方案:应用缓存被标记为已弃用,强烈建议使用 Service Workers 作为替代方案。

工作原理: 通过创建一个清单文件(manifest),列出需要缓存的资源。当用户首次访问网页时,浏览器会下载这些资源并存储在本地。后续访问会直接使用缓存的资源,而不是从服务器重新加载。

优点:

  • 可配置需要缓存的资源。
  • 网络无连接应用仍可用。
  • 本地读取缓存资源,提升访问速度,增强用户体验。
  • 减少请求,缓解服务器负担。

基本使用

1、创建清单文件xxx.appcache,文件中包括要缓存的资源列表过期策略等。

sh
CACHE MANIFEST
# 上面的一句代码是固定的,且必须在第一行

# 后面写注释

# 需要缓存的文件清单列表
CACHE:
../images/l1.jpg
../images/l2.jpg
* # 缓存所有文件

# 配置每一次都需要重新从服务器获取的文件清单列表
NETWORK:
../images/l3.jpg

# 配置如果文件无法获取则使用指定的文件进行替代
FALLBACK:
../images/l4.jpg ../images/banner_1.jpg
/ ../images/banner_1.jpg # /代表替代所有找不到的文件

CACHE MANIFEST

manifest文件格式

  • CACHE MANIFEST:开始。
  • CACHE:需要缓存的文件清单列表。
  • NETWORK:配置每一次都需要重新从服务器获取的文件清单列表。
  • FALLBACK:配置如果文件无法获取则使用指定的文件进行替代。

2、在 HTML 中引用清单文件

html
<!DOCTYPE html>
<html manifest="example.appcache">
<head>
    <title>My App</title>
    <link rel="stylesheet" href="styles.css">
    <script src="script.js"></script>
</head>
<body>
    <h1>Welcome to My App</h1>
</body>
</html>

注意事项

  • IIS需要配置: manifest文件需要配置正确的 MIME-type,即 text/cache-manifest。必须在 web 服务器上进行配置。

    image-20240924153122535

  • CACHE可以省略,这种情况下将需要缓存的资源写在 CACHE MANIFEST。

  • 可以指定多个 CACHE:NETWORK:FALLBACK:,无顺序限制。

  • 只有当 demo.appcache 文件内容发生改变时或者手动清除缓存后,才会重新缓存。

  • chrome 可以通过 chrome://appcache-internals/工具和离线(offline)模式来调试管理应用缓存

    image-20240924152659181

更新缓存条件

一旦文件被缓存,则浏览器会继续展示已缓存的版本,即使修改了服务器上的文件。为了确保浏览器更新缓存,也需要更新 manifest 文件,也就意味着一旦应用被缓存,它就会保持缓存直到发生下列情况:

  • 用户清空浏览器缓存。
  • manifest文件被修改(更新注释行中的日期和版本号是一种使浏览器重新缓存文件的办法)。
  • 由程序来更新应用缓存。